﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Utility;
using System.Threading;
using LuatChoi;

namespace Client
{
    public partial class frmClient : Form
    {
        public static ClientComputer client;
        private ClientList listClient;
        private bool chapNhanLoiMoi = true;
        private frmGame fGame;
        private bool dangchoi = false;

        public frmClient()
        {
            InitializeComponent();
        }


        public frmClient(ClientComputer cl)
            : this()
        {
            client = cl;
        }

        private void frmClient_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            this.Text = "Danh sách người chơi - " + client.UserName;
            client.ResetBuffer();
            client.Stream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, null);
            GuiYeuCauCapNhat();
        }



        void WriteCallback(IAsyncResult ar)
        {
            client.Stream.EndWrite(ar);
        }

        void ReadCallback(IAsyncResult ar)
        {
            try
            {
                client.Stream.EndRead(ar);
            }
            catch
            {
                MessageBox.Show("Mất kết nối với máy chủ!");
                Application.Exit();
                return;
            }

            try
            {

                var msg = new ChessMessage(client.Buffer);

                switch (msg.Type)
                {
                    case ChessMessageType.Login:
                        //mới có tài khoản login
                        break;
                    case ChessMessageType.Logout:
                        //mới có tài khoản logout
                        break;
                    case ChessMessageType.List:
                        //server muốn cập nhật danh sách
                        new Thread(() => CapNhatDanhSach(msg.Body)).Start();
                        break;
                    case ChessMessageType.Invite:
                        XuLyLoiMoi(msg);
                        break;
                    case ChessMessageType.Game:
                        XuLyGame(msg);
                        break;
                    case ChessMessageType.Chat:
                        XuLyChat(msg);
                        break;
                }
            }
            catch
            {

            }

            client.ResetBuffer();
            client.Stream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client);
        }

        private void XuLyChat(ChessMessage msg)
        {
            if (dangchoi)
            {
                var cmsg = new ChatMessage(msg.Body);
                fGame.LuuNhatKyChat(msg.SenderName, cmsg.Message);
            }
        }

        private void XuLyGame(ChessMessage msg)
        {
            var gmsg = new GameMessage(msg.Body);
            switch (gmsg.Type)
            {
                case GameMessageType.KhoiTao:
                    if (gmsg.ToaDoBatDau.X == 0)
                        KhoiTaoGame(msg.SenderName, Phe.Trang);
                    else
                        KhoiTaoGame(msg.SenderName, Phe.Den);
                    new Thread(() =>
                        {
                            dangchoi = true;
                            KhoiTaoSuKien();
                            fGame.ShowDialog();
                        }).Start();
                    break;
                case GameMessageType.BatDau:
                    fGame.BatDauChoi();
                    break;
                case GameMessageType.DiChuyen:
                    fGame.DiChuyenViTri(gmsg.ToaDoBatDau, gmsg.ToaDoKetThuc);
                    break;
                case GameMessageType.KetThuc:
                    break;
                case GameMessageType.Thang:
                    fGame.XuLyKetQua("Chúc mừng, bạn đã chiến thắng!",true);
                    break;
                case GameMessageType.Thua:
                    fGame.XuLyKetQua("Rất tiếc, bạn thua cuộc!",false);
                    break;
                case GameMessageType.DuocDi:
                    break;
                case GameMessageType.XinBoCuoc:
                    fGame.XuLyKetQua("Chúc mừng bạn, đối phương đã chịu thua",true);
                    break;
                case GameMessageType.ThoatGiuaChung:
                    MessageBox.Show("Đối phương đã thoát");
                    fGame.Close();
                    chapNhanLoiMoi = true;
                    //fGame.Dispose();
                    //fGame = null;
                    break;
                case GameMessageType.PhongTot:
                    fGame.PhongCapChoTot(gmsg.ToaDoBatDau, gmsg.ToaDoKetThuc, gmsg.Comment);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        void XuLyLoiMoi(ChessMessage msg)
        {
            lock ("loimoi")
            {
                if (chapNhanLoiMoi)
                {
                    chapNhanLoiMoi = false;
                    var ivm = new InviteMessage(msg.Body);
                    switch (ivm.Type)
                    {
                        case InviteMessageType.Send:
                            string mbox = string.Format("{0} đã thách đấu với bạn, bạn có đồng ý không?",
                                                        msg.SenderName);
                            var dr = MessageBox.Show(mbox, "", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                            if (dr == DialogResult.Yes)
                            {
                                ivm.Type = InviteMessageType.OK;
                            }
                            else
                            {
                                ivm.Type = InviteMessageType.Cancel;
                                chapNhanLoiMoi = true;
                            }
                            var inviteMsg = CreateNewMessage(ChessMessageType.Invite);
                            ivm.Target = msg.SenderName;
                            inviteMsg.Body = ivm.ToString();
                            Send(inviteMsg);
                            break;
                    }

                }
            }
        }
        void CapNhatDanhSach(string data)
        {
            listClient = new ClientList(data);
            lvDanhSachClient.Items.Clear();


            foreach (ClientInfo clientInfo in listClient.Clients)
            {
                try
                {
                    ListViewItem item;
                    if (clientInfo.UserName.Equals(client.UserName))
                    {
                        item = new ListViewItem(clientInfo.UserName);
                        item.SubItems.Add("Tôi");
                        item.ForeColor = Color.OrangeRed;
                    }
                    else
                    {
                        item = new ListViewItem(clientInfo.UserName);
                        item.SubItems.Add(clientInfo.Status == ClientStatus.Free ? "Đang chờ" : "Đang chơi");
                    }

                    lvDanhSachClient.Items.Add(item);
                }
                catch
                {
                }

            }
        }

        void GuiYeuCauCapNhat()
        {
            var msg = CreateNewMessage(ChessMessageType.List);
            var buff = msg.ToByteArray();
            client.Stream.BeginWrite(buff, 0, buff.Length, WriteCallback, client);
        }

        private void frmClient_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                var msg = CreateNewMessage(ChessMessageType.Logout);
                Send(msg);
            }
            catch
            {

            }

        }




        private void lvDanhSachClient_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lvDanhSachClient.SelectedItems.Count == 1)
            {
                try
                {
                    var i = lvDanhSachClient.SelectedIndices[0];
                    ctmThachDau.Enabled = (listClient[i].Status == ClientStatus.Free) && !listClient[i].UserName.Equals(client.UserName);
                }
                catch
                {
                    GuiYeuCauCapNhat();
                }

            }
        }

        private void ctmThachDau_Click(object sender, EventArgs e)
        {
            var i = lvDanhSachClient.SelectedIndices[0];
            var user = listClient[i].UserName;
            var msg = CreateNewMessage(ChessMessageType.Invite);
            var ivm = new InviteMessage()
                {
                    Target = user,
                    Type = InviteMessageType.Send
                };
            msg.Body = ivm.ToString();
            Send(msg);

        }

        private void ctmTaiLai_Click(object sender, EventArgs e)
        {
            GuiYeuCauCapNhat();
        }



        #region  form game và các sự kiện

        void KhoiTaoGame(string tenDoiPhuong, Phe pheMinh)
        {
            fGame = new frmGame(tenDoiPhuong, pheMinh);
        }

        void KhoiTaoSuKien()
        {
            fGame.ThayDoiHienThiDanhSach += ThayDoiHienThi;
            fGame.TroChuyen += fGame_TroChuyen;
            fGame.BatDauGame += fGame_BatDauGame;
            fGame.DiChuyen += fGame_DiChuyen;
            fGame.Thoat += fGame_Thoat;
            fGame.PhongTot += fGame_PhongTot;
            fGame.BoCuoc += fGame_BoCuoc;
        }

        void fGame_PhongTot(object sender, PhongTotArg e)
        {
            var gmsg = CreateNewGameMessage(GameMessageType.PhongTot);
            gmsg.ToaDoBatDau = e.BatDau;
            gmsg.ToaDoKetThuc = e.KetThuc;
            gmsg.Comment = e.TenQuan;
            var msg = CreateNewMessage(ChessMessageType.Game);
            msg.Body = gmsg.ToString();
            Send(msg);
        }

        void fGame_Thoat(object sender, EventArgs e)
        {
            var gmsg = CreateNewGameMessage(GameMessageType.ThoatGiuaChung);
            var msg = CreateNewMessage(ChessMessageType.Game);
            msg.Body = gmsg.ToString();
            Send(msg);
            chapNhanLoiMoi = true;
        }

        void fGame_BoCuoc(object sender, EventArgs e)
        {
            var gmsg = CreateNewGameMessage(GameMessageType.XinBoCuoc);
            var msg = CreateNewMessage(ChessMessageType.Game);
            msg.Body = gmsg.ToString();
            Send(msg);
            chapNhanLoiMoi = true;
        }

        void fGame_DiChuyen(object sender, DiChuyenArgs e)
        {
            var gmsg = CreateNewGameMessage(GameMessageType.DiChuyen);
            gmsg.ToaDoBatDau = e.BatDau;
            gmsg.ToaDoKetThuc = e.KetThuc;
            var msg = CreateNewMessage(ChessMessageType.Game);
            msg.Body = gmsg.ToString();
            Send(msg);
        }

        void fGame_BatDauGame(object sender, EventArgs e)
        {
            var gmsg = CreateNewGameMessage(GameMessageType.BatDau);
            var msg = CreateNewMessage(ChessMessageType.Game);
            msg.Body = gmsg.ToString();
            Send(msg);
        }

        private void fGame_TroChuyen(object sender, ChatArgs e)
        {
            var chatMsg = CreateNewChatMessage(e.SendTo, e.Message);
            var msg = CreateNewMessage(ChessMessageType.Chat);
            msg.Body = chatMsg.ToString();
            Send(msg);
        }

        private void ThayDoiHienThi(object sender, EventArgs eventArgs)
        {
            if ((bool)sender)
                this.WindowState = FormWindowState.Minimized;
            else
                this.WindowState = FormWindowState.Normal;
        }

        #endregion

        #region Tạo và gửi thông điệp

        private void Send(ChessMessage msg)
        {
            var buff = msg.ToByteArray();
            client.Stream.BeginWrite(buff, 0, buff.Length, WriteCallback, client);
        }



        private ChessMessage CreateNewMessage(ChessMessageType type = ChessMessageType.Other)
        {
            return new ChessMessage()
                {
                    Type = type,
                    SenderName = client.UserName
                };
        }

        private ChatMessage CreateNewChatMessage(string target, string msg)
        {
            return new ChatMessage()
            {
                Message = msg,
                SendTo = target
            };
        }

        private GameMessage CreateNewGameMessage(GameMessageType type)
        {
            return new GameMessage()
            {
                Type = type,
            };
        }
        #endregion

        //private void boDemThoiGian_Tick(object sender, EventArgs e)
        //{
        //    if (fGame != null && fGame.TrangThai.DangChoi)
        //    {
        //        fGame.TinhToanThoiGian();
        //    }
        //}
    }


}
